home *** CD-ROM | disk | FTP | other *** search
- /* xlbfun.c - xlisp basic builtin functions */
-
- #include "xlisp.h"
-
- /* external variables */
- extern NODE *xlstack;
- extern NODE *s_lambda,*s_macro;
- extern NODE *s_comma,*s_comat;
- extern NODE *s_unbound;
- extern char gsprefix[];
- extern int gsnumber;
-
- /* forward declarations */
- FORWARD NODE *bquote1();
- FORWARD NODE *defun();
- FORWARD NODE *makesymbol();
-
- /* xeval - the builtin function 'eval' */
- NODE *xeval(args)
- NODE *args;
- {
- NODE *oldstk,expr,*val;
-
- /* create a new stack frame */
- oldstk = xlsave(&expr,NULL);
-
- /* get the expression to evaluate */
- expr.n_ptr = xlarg(&args);
- xllastarg(args);
-
- /* evaluate the expression */
- val = xleval(expr.n_ptr);
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the expression evaluated */
- return (val);
- }
-
- /* xapply - the builtin function 'apply' */
- NODE *xapply(args)
- NODE *args;
- {
- NODE *oldstk,fun,arglist,*val;
-
- /* create a new stack frame */
- oldstk = xlsave(&fun,&arglist,NULL);
-
- /* get the function and argument list */
- fun.n_ptr = xlarg(&args);
- arglist.n_ptr = xlarg(&args);
- xllastarg(args);
-
- /* if the function is a symbol, get its value */
- if (symbolp(fun.n_ptr))
- fun.n_ptr = xleval(fun.n_ptr);
-
- /* apply the function to the arguments */
- val = xlapply(fun.n_ptr,arglist.n_ptr);
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the expression evaluated */
- return (val);
- }
-
- /* xfuncall - the builtin function 'funcall' */
- NODE *xfuncall(args)
- NODE *args;
- {
- NODE *oldstk,fun,arglist,*val;
-
- /* create a new stack frame */
- oldstk = xlsave(&fun,&arglist,NULL);
-
- /* get the function and argument list */
- fun.n_ptr = xlarg(&args);
- arglist.n_ptr = args;
-
- /* if the function is a symbol, get its value */
- if (symbolp(fun.n_ptr))
- fun.n_ptr = xleval(fun.n_ptr);
-
- /* apply the function to the arguments */
- val = xlapply(fun.n_ptr,arglist.n_ptr);
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the expression evaluated */
- return (val);
- }
-
- /* xquote - builtin function to quote an expression */
- NODE *xquote(args)
- NODE *args;
- {
- NODE *arg;
-
- /* get the argument */
- arg = xlarg(&args);
- xllastarg(args);
-
- /* return the quoted expression */
- return (arg);
- }
-
- /* xbquote - back quote function */
- NODE *xbquote(args)
- NODE *args;
- {
- NODE *oldstk,expr,*val;
-
- /* create a new stack frame */
- oldstk = xlsave(&expr,NULL);
-
- /* get the expression */
- expr.n_ptr = xlarg(&args);
- xllastarg(args);
-
- /* fill in the template */
- val = bquote1(expr.n_ptr);
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the result */
- return (val);
- }
-
- /* bquote1 - back quote helper function */
- LOCAL NODE *bquote1(expr)
- NODE *expr;
- {
- NODE *oldstk,val,list,*last,*new;
-
- /* handle atoms */
- if (atom(expr))
- val.n_ptr = expr;
-
- /* handle (comma <expr>) */
- else if (car(expr) == s_comma) {
- if (atom(cdr(expr)))
- xlfail("bad comma expression");
- val.n_ptr = xleval(car(cdr(expr)));
- }
-
- /* handle ((comma-at <expr>) ... ) */
- else if (consp(car(expr)) && car(car(expr)) == s_comat) {
- oldstk = xlsave(&list,&val,NULL);
- if (atom(cdr(car(expr))))
- xlfail("bad comma-at expression");
- list.n_ptr = xleval(car(cdr(car(expr))));
- for (last = NULL; consp(list.n_ptr); list.n_ptr = cdr(list.n_ptr)) {
- new = newnode(LIST);
- rplaca(new,car(list.n_ptr));
- if (last)
- rplacd(last,new);
- else
- val.n_ptr = new;
- last = new;
- }
- if (last)
- rplacd(last,bquote1(cdr(expr)));
- else
- val.n_ptr = bquote1(cdr(expr));
- xlstack = oldstk;
- }
-
- /* handle any other list */
- else {
- oldstk = xlsave(&val,NULL);
- val.n_ptr = newnode(LIST);
- rplaca(val.n_ptr,bquote1(car(expr)));
- rplacd(val.n_ptr,bquote1(cdr(expr)));
- xlstack = oldstk;
- }
-
- /* return the result */
- return (val.n_ptr);
- }
-
- /* xset - builtin function set */
- NODE *xset(args)
- NODE *args;
- {
- NODE *sym,*val;
-
- /* get the symbol and new value */
- sym = xlmatch(SYM,&args);
- val = xlarg(&args);
- xllastarg(args);
-
- /* assign the symbol the value of argument 2 and the return value */
- assign(sym,val);
-
- /* return the result value */
- return (val);
- }
-
- /* xsetq - builtin function setq */
- NODE *xsetq(args)
- NODE *args;
- {
- NODE *oldstk,arg,sym,val;
-
- /* create a new stack frame */
- oldstk = xlsave(&arg,&sym,&val,NULL);
-
- /* initialize */
- arg.n_ptr = args;
-
- /* handle each pair of arguments */
- while (arg.n_ptr) {
- sym.n_ptr = xlmatch(SYM,&arg.n_ptr);
- val.n_ptr = xlevarg(&arg.n_ptr);
- assign(sym.n_ptr,val.n_ptr);
- }
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the result value */
- return (val.n_ptr);
- }
-
- /* xdefun - builtin function 'defun' */
- NODE *xdefun(args)
- NODE *args;
- {
- return (defun(args,s_lambda));
- }
-
- /* xdefmacro - builtin function 'defmacro' */
- NODE *xdefmacro(args)
- NODE *args;
- {
- return (defun(args,s_macro));
- }
-
- /* defun - internal function definition routine */
- LOCAL NODE *defun(args,type)
- NODE *args,*type;
- {
- NODE *oldstk,sym,fargs,fun;
-
- /* create a new stack frame */
- oldstk = xlsave(&sym,&fargs,&fun,NULL);
-
- /* get the function symbol and formal argument list */
- sym.n_ptr = xlmatch(SYM,&args);
- fargs.n_ptr = xlmatch(LIST,&args);
-
- /* create a new function definition */
- fun.n_ptr = newnode(LIST);
- rplaca(fun.n_ptr,type);
- rplacd(fun.n_ptr,newnode(LIST));
- rplaca(cdr(fun.n_ptr),fargs.n_ptr);
- rplacd(cdr(fun.n_ptr),args);
-
- /* make the symbol point to a new function definition */
- assign(sym.n_ptr,fun.n_ptr);
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the function symbol */
- return (sym.n_ptr);
- }
-
- /* xgensym - generate a symbol */
- NODE *xgensym(args)
- NODE *args;
- {
- char sym[STRMAX+1];
- NODE *x;
-
- /* get the prefix or number */
- if (args) {
- x = xlarg(&args);
- switch (ntype(x)) {
- case STR:
- strcpy(gsprefix,x->n_str);
- break;
- case INT:
- gsnumber = x->n_int;
- break;
- default:
- xlfail("bad argument type");
- }
- }
- xllastarg(args);
-
- /* create the pname of the new symbol */
- sprintf(sym,"%s%d",gsprefix,gsnumber++);
-
- /* make a symbol with this print name */
- return (xlmakesym(sym,DYNAMIC));
- }
-
- /* xmakesymbol - make a new uninterned symbol */
- NODE *xmakesymbol(args)
- NODE *args;
- {
- return (makesymbol(args,FALSE));
- }
-
- /* xintern - make a new interned symbol */
- NODE *xintern(args)
- NODE *args;
- {
- return (makesymbol(args,TRUE));
- }
-
- /* makesymbol - make a new symbol */
- LOCAL NODE *makesymbol(args,iflag)
- NODE *args; int iflag;
- {
- NODE *oldstk,pname,*val;
- char *str;
-
- /* create a new stack frame */
- oldstk = xlsave(&pname,NULL);
-
- /* get the print name of the symbol to intern */
- pname.n_ptr = xlmatch(STR,&args);
- xllastarg(args);
-
- /* make the symbol */
- str = pname.n_ptr->n_str;
- val = (iflag ? xlenter(str,DYNAMIC) : xlmakesym(str,DYNAMIC));
-
- /* restore the previous stack frame */
- xlstack = oldstk;
-
- /* return the symbol */
- return (val);
- }
-
- /* xsymname - get the print name of a symbol */
- NODE *xsymname(args)
- NODE *args;
- {
- NODE *sym;
-
- /* get the symbol */
- sym = xlmatch(SYM,&args);
- xllastarg(args);
-
- /* return the print name */
- return (car(sym->n_symplist));
- }
-
- /* xsymvalue - get the print value of a symbol */
- NODE *xsymvalue(args)
- NODE *args;
- {
- NODE *sym;
-
- /* get the symbol */
- sym = xlmatch(SYM,&args);
- xllastarg(args);
-
- /* check for an unbound symbol */
- while (sym->n_symvalue == s_unbound)
- xlunbound(sym);
-
- /* return the value */
- return (sym->n_symvalue);
- }
-
- /* xsymplist - get the property list of a symbol */
- NODE *xsymplist(args)
- NODE *args;
- {
- NODE *sym;
-
- /* get the symbol */
- sym = xlmatch(SYM,&args);
- xllastarg(args);
-
- /* return the property list */
- return (cdr(sym->n_symplist));
- }
-
- /* xget - get the value of a property */
- NODE *xget(args)
- NODE *args;
- {
- NODE *sym,*prp;
-
- /* get the symbol and property */
- sym = xlmatch(SYM,&args);
- prp = xlmatch(SYM,&args);
- xllastarg(args);
-
- /* retrieve the property value */
- return (xlgetprop(sym,prp));
- }
-
- /* xremprop - remove a property value from a property list */
- NODE *xremprop(args)
- NODE *args;
- {
- NODE *sym,*prp;
-
- /* get the symbol and property */
- sym = xlmatch(SYM,&args);
- prp = xlmatch(SYM,&args);
- xllastarg(args);
-
- /* remove the property */
- xlremprop(sym,prp);
-
- /* return nil */
- return (NULL);
- }